const webpack = require("webpack");
const path = require("path");
const HTMLPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// const glob = require('glob-all');
// const PurgecssPlugin = require('purgecss-webpack-plugin'); // 这个玩意不能提取vue文件里面的style
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const CompressionWebpackPlugin = require("compression-webpack-plugin");

const HappyPack = require("happypack"); // 生产环境配置 多线程打包 小项目会变慢

const HappyPackThreadPool = HappyPack.ThreadPool({ size: 2 });

const config = {
	mode: 'production', // 开发模式, (不会自动压缩 ok)
	entry: {
		vendor: ["vue", "element-ui", "jquery", "lodash", "underscore"],
		main: path.join(__dirname, "src/main.js"),
		// group: path.join(__dirname, "public", "group.js")
	},
	output: {
		filename: "scripts/[name].[hash:8].js",  // 打包出来的主文件名称,带有1个8位的hash字符串
		path: path.join(__dirname, "dist") // 必须是绝对路径
		// publicPath: './',
		// 通过devServer访问路径, script标签src前面会添加上 dist , 打包到cdn时,可以插入cdn前缀
	},
	module: {
		rules: [
			{
    		test: /\.js$/, //支持箭头函数，class等
		    use: [{
		    	loader: 'babel-loader',
		    }], 
		    exclude: [
		        path.join(__dirname, 'node_modules'), // 由于node_modules都是编译过的文件，这里我们不让babel去处理其下面的js文件
		    ],
    	},
			{
				test: /\.vue$/,
				loader: "vue-loader"
			},
			{
				test: /\.s?css$/,
				use: [{ 
					loader: MiniCssExtractPlugin.loader,
					options: {
		    		puclicPath: "../../", // 这个配置默认用 output 下面的 publicPath
		    	}
				}, 
					"css-loader",  "sass-loader", "postcss-loader"
					// 从后往前执行
					// style-loader 把 css-loader 生成的 样式 插入到 <style> </style>
				],
				exclude: path.resolve(__dirname, 'node_modules')
			},
			{
				test: /\.(pn|jp|jpe|sv)g|git|ico$/,
				use: [
					{ loader: "url-loader",
						options: {
        			limit: 1024 * 20, // 20kb 以下的图片转换为base64
        			name: '[name]-[hash:4].[ext]',
        			outputPath: "imgs"
    				}
    			},
    		]
    	},
    	{
    		test: /\.(ttf|eot|otf|woff|woff2)$/,
    		loader: "file-loader",
    		options: {
    			name: '[name].[ext]',
    			outputPath: "fonts"
    			// name: '/fonts/[path][name].[ext]' 
    			// [path] 指向了 node_module/element-ui/lib/theme-chalk/fonts
    			// 因为字体文件是在那个文件夹里面的
  			}
    	}
    ]
	},
	plugins: [
		new HTMLPlugin({
			filename: "index.html",
			template: path.join(__dirname, "public", 'index.html'),
			inject: true,
			// minify: {
			// 	removeComments: true,
			// 	minifyCSS: true,
			// 	collapseWhitespace: true,// 删除空格和换行
			// }
		}),
		 // make sure to include the plugin!
    new VueLoaderPlugin(),

    new MiniCssExtractPlugin({
    	filename: "/styles/[name].[hash:8].css", // 打包到css文件夹里面
    	chunkFilename: "[id].css"
    }),
    new CopyWebpackPlugin({
    	patterns: [{
    		from: path.join(__dirname, "public", "favicon.ico"),
    		to: path.join(__dirname, "dist", "[name].[ext]"),
    		flatten: true,
    	}, {
    		from: path.join(__dirname, "public", "static"),
    		to: path.join(__dirname, "dist", "static"),
    		flatten: true,
    	}]
    }),

    new CleanWebpackPlugin({
    	dry: false,
    	cleanStaleWebpackAssets: true,
    }),


    // new webpack.DefinePlugin({
    // 	Description: "定义 *编译时* 的全局变量"
    // })

    // 全局变量, 模块中无需 require 引入
    new webpack.ProvidePlugin({
    	$: "jquery",
    	_: "lodash"
    })



    // new PurgecssPlugin({
      // paths: glob.sync([
      	// path.join(__dirname, "public", "index.html"),
      	// path.join(__dirname, "dist", "index.html"),
      	// path.join(__dirname, "dist", "*.js"),
      // ]),
    // }),
   
	],

	devServer: {
		overlay: {  // webpack编译出现错误，则显示到网页上
    	errors: true,
    },
    // open: true, // 自动打开浏览器
    hot: true, // 不刷新热加载数据
	},
	resolve: {
    alias: {
      '@': path.resolve(__dirname),
    },
    extensions: ['.js', '.json', '.css', '.vue'] // 这几个文件后缀不用写了, 同名就要写
  },
  optimization: {
  	splitChunks: {
  		chunks: "all",
  		minSize: 0,
  		maxSize: 1024 * 100, // 单位: kb 每个打包出来的文件的最大尺寸, 写的越小,打出来的包越多
  		minChunks: 1, // 表示被引用次数，默认为1, 被引用1次的代码抽离到公共代码里面
  	}
  }
}

const env = process.env.NODE_ENV;

if(env === "production"){
	config.devtool = 'cheap-module-source-map'
	config.plugins.push(
		new OptimizeCssAssetsWebpackPlugin(),
		
		new CompressionWebpackPlugin({
			test: /\.(html$|css$|js$)/,
			threshold: 10 * 1024, // > 10 kb 压缩
			deleteOriginalAssets: true, // 删除源文件?
		}),

		new HappyPack({
			id: "babel",
			loaders: ["babel-loader"],
			threadPool: HappyPackThreadPool 
		}),

		new HappyPack({
			id: "vue",
			loaders: {
				loader: "vue-loader",
			},
			threadPool: HappyPackThreadPool 
		}),
	);
}else if( env === 'development' ){
	config.devtool = 'source-map'
}

module.exports = config;